package edu.pucsp.predatorprey.tela;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;

import edu.pucsp.predatorprey.simulador.java.criatura.AbstractCriatura;
import edu.pucsp.predatorprey.simulador.java.posicao.impl.Posicao;
import edu.pucsp.predatorprey.simulador.java.terreno.impl.TerrenoImpl;
import edu.pucsp.predatorprey.tela.observer.Observador;
import edu.pucsp.predatorprey.tela.util.CicloDeVida;

public class TerrenoCanvas extends Canvas implements Observador, PosicaoListener {

	private final Modelo modelo;

	public TerrenoCanvas(Modelo modelo) {
		this.modelo = modelo;
		this.setBackground(Color.WHITE);
	}

	@Override
	public void mudouPosicao(Posicao posicao) {
		this.mudouPosicao(posicao, this.getGraphics());
	}

	@Override
	public void atualizar(CicloDeVida cicloDeVida) {
		if (cicloDeVida.equals(CicloDeVida.COMECOU)) {
			this.repaint();
		}
	}

	@Override
	public void paint(Graphics g) {
		this.desenharCriaturas(this.modelo.getPosicaoCriaturas(), g);
	}

	private void mudouPosicao(Posicao posicao, Graphics g) {
		AbstractCriatura criatura = this.modelo.getPosicaoCriaturas()[posicao.getX()][posicao.getY()];

		g.setColor(this.getCreatureColor(criatura));

		Posicao posicaoRelativa = this.obterPosicaoRelativa(posicao);
		g.fillRect(posicaoRelativa.getX(), posicaoRelativa.getY(), this.obterLarguraQuadrado(), this.obterAlturaQuadrado());
	}

	private void desenharCriaturas(AbstractCriatura[][] abstractCriaturas, Graphics g) {
		for (int i = 0; i < abstractCriaturas.length; i++) {
			for (int j = 0; j < abstractCriaturas[i].length; j++) {
				this.mudouPosicao(new Posicao(i, j), g);
			}
		}
	}

	private Color getCreatureColor(AbstractCriatura criatura) {
		Color color = Color.WHITE;
		if (criatura != null) {
			if (criatura.isPredador()) {
				color = Color.RED;
			} else {
				color = Color.BLUE;
			}
		}
		return color;
	}

	private int obterLarguraQuadrado() {
		return (int) Math.round((double) this.getWidth() / (double) TerrenoImpl.WIDTH);
	}

	private int obterAlturaQuadrado() {
		return (int) Math.round((double) this.getHeight() / (double) TerrenoImpl.HEIGHT);
	}

	private Posicao obterPosicaoRelativa(Posicao pos) {
		int x = pos.getX() * this.getWidth() / TerrenoImpl.WIDTH;
		int y = pos.getY() * this.getHeight() / TerrenoImpl.HEIGHT;
		return new Posicao(x, y);
	}
}
